home *** CD-ROM | disk | FTP | other *** search
/ Programming Windows 95 with MFC / Programming Windows 95 with MFC (Microsoft Programming Series)(097-0001465)(1996).iso / NT / CODE / CHAP14 / THREADS / THREADS.CPP < prev    next >
C/C++ Source or Header  |  1996-04-05  |  6KB  |  213 lines

  1. //***********************************************************************
  2. //
  3. //  Threads.cpp
  4. //
  5. //***********************************************************************
  6.  
  7. #include <afxwin.h>
  8. #include <math.h>
  9. #include "Resource.h"
  10. #include "Threads.h"
  11.  
  12. #define RADIUS 120
  13.  
  14. CMyApp myApp;
  15.  
  16. /////////////////////////////////////////////////////////////////////////
  17. // CMyApp member functions
  18.  
  19. BOOL CMyApp::InitInstance ()
  20. {
  21.     m_pMainWnd = new CMainWindow;
  22.     m_pMainWnd->ShowWindow (m_nCmdShow);
  23.     m_pMainWnd->UpdateWindow ();
  24.     return TRUE;
  25. }
  26.  
  27. /////////////////////////////////////////////////////////////////////////
  28. // CMainWindow message map and member functions
  29.  
  30. BEGIN_MESSAGE_MAP (CMainWindow, CFrameWnd)
  31.     ON_WM_CLOSE ()
  32.     ON_COMMAND_RANGE (IDM_THREAD_1, IDM_THREAD_4, OnToggleThread)
  33.     ON_COMMAND (IDM_FRIENDLY_THREADS, OnFriendlyThreads)
  34.     ON_UPDATE_COMMAND_UI_RANGE (IDM_THREAD_1, IDM_THREAD_4,
  35.         OnUpdateThreadUI)
  36.     ON_UPDATE_COMMAND_UI (IDM_FRIENDLY_THREADS,
  37.         OnUpdateFriendlyThreadsUI)
  38.     ON_COMMAND (IDM_EXIT, OnExit)
  39. END_MESSAGE_MAP ()
  40.  
  41. CMainWindow::CMainWindow ()
  42. {
  43.     m_bFriendlyThreads = FALSE;
  44.     for (int i=0; i<4; i++) {
  45.         m_pThread[i] = NULL;
  46.         m_bContinue[i] = FALSE;
  47.     }
  48.  
  49.     CString strWndClass = AfxRegisterWndClass (
  50.         0,
  51.         myApp.LoadStandardCursor (IDC_ARROW),
  52.         (HBRUSH) (COLOR_3DFACE + 1),
  53.         myApp.LoadStandardIcon (IDI_APPLICATION)
  54.     );
  55.  
  56.     Create (strWndClass, "Threads", WS_OVERLAPPEDWINDOW, rectDefault,
  57.         NULL, MAKEINTRESOURCE (IDR_MAINFRAME));
  58.  
  59.     LoadAccelTable (MAKEINTRESOURCE (IDR_MAINFRAME));
  60. }
  61.  
  62. BOOL CMainWindow::PreCreateWindow (CREATESTRUCT& cs)
  63. {
  64.     if (!CFrameWnd::PreCreateWindow (cs))
  65.         return FALSE;
  66.  
  67.     cs.dwExStyle &= ~WS_EX_CLIENTEDGE;
  68.     return TRUE;
  69. }
  70.  
  71. void CMainWindow::OnClose ()
  72. {
  73.     for (int i=0; i<4; i++) {
  74.         if (m_pThread[i] != NULL)
  75.             delete m_pThread[i];
  76.     }
  77.     CFrameWnd::OnClose ();
  78. }
  79.  
  80. void CMainWindow::OnToggleThread (UINT nID)
  81. {
  82.     static int nCoords[4][2] = {
  83.         RADIUS,     -RADIUS,        // Thread 1
  84.         RADIUS * 3, -RADIUS,        // Thread 2
  85.         RADIUS,     -RADIUS * 3,    // Thread 3
  86.         RADIUS * 3, -RADIUS * 3     // Thread 4
  87.     };
  88.  
  89.     UINT i = nID - IDM_THREAD_1;
  90.  
  91.     if (m_pThread[i] == NULL) { // Create a thread
  92.         THREADPARMS* pThreadParms = new THREADPARMS;
  93.         pThreadParms->point.x = nCoords[i][0];
  94.         pThreadParms->point.y = nCoords[i][1];
  95.         pThreadParms->pContFlag = &m_bContinue[i];
  96.         pThreadParms->pFriendFlag = &m_bFriendlyThreads;
  97.         pThreadParms->lParam = (LPARAM) this;
  98.  
  99.         m_bContinue[i] = TRUE;
  100.         m_pThread[i] = AfxBeginThread (ThreadFunc, pThreadParms);
  101.     }
  102.     else { // Terminate a thread
  103.         HANDLE hThread = m_pThread[i]->m_hThread;
  104.         m_bContinue[i] = FALSE;
  105.         ::WaitForSingleObject (hThread, INFINITE);
  106.         m_pThread[i] = NULL;
  107.     }
  108. }
  109.  
  110. void CMainWindow::OnFriendlyThreads ()
  111. {
  112.     m_bFriendlyThreads = m_bFriendlyThreads ? FALSE : TRUE;
  113. }
  114.  
  115. void CMainWindow::OnUpdateFriendlyThreadsUI (CCmdUI* pCmdUI)
  116. {
  117.     pCmdUI->SetCheck (m_bFriendlyThreads);
  118. }
  119.  
  120. void CMainWindow::OnExit ()
  121. {
  122.     SendMessage (WM_CLOSE, 0, 0);
  123. }
  124.  
  125. void CMainWindow::OnUpdateThreadUI (CCmdUI* pCmdUI)
  126. {
  127.     UINT i = pCmdUI->m_nID - IDM_THREAD_1;
  128.  
  129.     CString string;
  130.     if (m_pThread[i] == NULL)
  131.         string.Format ("Start Thread &%d\tF%d", i + 1, i + 1);
  132.     else
  133.         string.Format ("Terminate Thread &%d\tF%d", i + 1, i + 1);
  134.  
  135.     pCmdUI->SetText (string);
  136. }
  137.  
  138. void CMainWindow::DrawHand (CDC* pDC, int nLength, int nScale,
  139.     int nDegrees, COLORREF crColor)
  140. {
  141.     CPoint point[4];
  142.     double nRadians = (double) nDegrees * 0.017453292;
  143.  
  144.     point[0].x = (int) (nLength * sin (nRadians));
  145.     point[0].y = (int) (nLength * cos (nRadians));
  146.  
  147.     point[2].x = -point[0].x / nScale;
  148.     point[2].y = -point[0].y / nScale;
  149.  
  150.     point[1].x = -point[2].y;
  151.     point[1].y = point[2].x;
  152.  
  153.     point[3].x = -point[1].x;
  154.     point[3].y = -point[1].y;
  155.  
  156.     CPen pen (PS_SOLID, 0, crColor);
  157.     CPen* pOldPen = pDC->SelectObject (&pen);
  158.  
  159.     pDC->MoveTo (point[0]);
  160.     pDC->LineTo (point[1]);
  161.     pDC->LineTo (point[2]);
  162.     pDC->LineTo (point[3]);
  163.     pDC->LineTo (point[0]);
  164.  
  165.     pDC->SelectObject (pOldPen);
  166. }
  167.  
  168. UINT CMainWindow::ThreadFunc (LPVOID pParam)
  169. {
  170.     static COLORREF crColors[8] = {
  171.         RGB (  0,   0,   0),    // Black
  172.         RGB (  0,   0, 255),    // Blue
  173.         RGB (  0, 255,   0),    // Green
  174.         RGB (  0, 255, 255),    // Cyan
  175.         RGB (255,   0,   0),    // Red
  176.         RGB (255,   0, 255),    // Magenta
  177.         RGB (255, 255,   0),    // Yellow
  178.         RGB (255, 255, 255)     // White
  179.     };
  180.  
  181.     THREADPARMS* pThreadParms = (THREADPARMS*) pParam;
  182.     CPoint point = pThreadParms->point;
  183.     BOOL* pContFlag = pThreadParms->pContFlag;
  184.     BOOL* pFriendFlag = pThreadParms->pFriendFlag;
  185.     CMainWindow* pWnd = (CMainWindow*) pThreadParms->lParam;
  186.     delete pThreadParms;
  187.  
  188.     int nMinute = 0;
  189.     int nIndex = 0;
  190.  
  191.     while (*pContFlag) {
  192.         CDC* pDC = pWnd->GetDC ();
  193.         pDC->SetMapMode (MM_LOENGLISH);
  194.  
  195.         CPoint org = point;
  196.         pDC->LPtoDP (&org);
  197.         pDC->SetViewportOrg (org.x, org.y);
  198.  
  199.         pWnd->DrawHand (pDC, RADIUS, 8, nMinute * 6, crColors[nIndex]);
  200.         pWnd->ReleaseDC (pDC);
  201.  
  202.         if (++nMinute == 60) {
  203.             nMinute = 0;
  204.             if (++nIndex == 8)
  205.                 nIndex = 0;
  206.         }
  207.  
  208.         if (*pFriendFlag)
  209.             ::Sleep (0);
  210.     }
  211.     return 0;
  212. }
  213.